/**
 * @file app\relay\relay.c
 *
 * Copyright (C) 2023
 *
 * dp_key.c is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author zhuodada
 *
 * @encoding utf-8
 */

/*---------- includes ----------*/
#include "device.h"
#include "gpio_group.h"
#include "protocol_mobus.h"
#include "resources.h"
#include "soft_timer.h"
#include "storage.h"

/*---------- macro ----------*/
#define TAG "Relay"

/*---------- type define ----------*/
/*---------- variable prototype ----------*/
/*---------- function prototype ----------*/
/*---------- variable ----------*/
void* dev_relay;
static uint8_t tempbuff[1] = { 0 };
/*---------- function  ----------*/
static void _timer_expired(timer_handle_t timer) {
    gpio_group_describe_t* pdesc = NULL;
    if (no_storage.led_temp_variable.dev_work_mode != LED_MODE_WORK)
        return;
    pdesc = (((device_t*)dev_relay)->pdesc);
    assert(pdesc);
    for (uint8_t i = 0; i < pdesc->group_num_max; i++) {
        if (no_storage.temp_relay.relay_actionflag[i] == true) {
            if (no_storage.temp_relay.occupyflag[i] == false) {
                if (CY_EOK == device_ioctl(dev_relay, ((i + 1) << 8) | IOCTL_GROUP_SET, (void*)&no_storage.temp_relay.relay_out[i])) {
                     // report relayx sta
                    if (no_storage.temp_relay.relay_out[i] == true) {
                        tempbuff[0] = 1;
                        protocol_mobus_dev_report(MOBUS_FRAME_TYPE_COMMAND, i + 1, tempbuff, 1);
                    }
                    else if (no_storage.temp_relay.relay_out[i] == false) {
                        tempbuff[0] = 0;
                        protocol_mobus_dev_report(MOBUS_FRAME_TYPE_COMMAND, i + 1, tempbuff, 1);
                    }
                }
                no_storage.temp_relay.relay_actionflag[i] = false;
            }
        }
    }
}

void open_relay_ornot_for_others(uint8_t num, bool sta) {
    no_storage.temp_relay.relay_actionflag[num] = true;
    no_storage.temp_relay.relay_out[num] = sta;
    if (no_storage.temp_relay.occupyflag[num] == true) {
        tempbuff[0] = 0x80 | sta;
        protocol_mobus_dev_report(MOBUS_FRAME_TYPE_COMMAND, num + 1, tempbuff, 1);
    }
}
void app_relay_poll(void) {
    void* proc_timer;

    dev_relay = resources_get("dev_relay");
    assert(dev_relay);

    /* create a timer for proc polling */
    proc_timer = soft_timer_create("RelayProcTimer", SFTIM_MODE_REPEAT,
        __ms2ticks(100), NULL, _timer_expired);
    assert(proc_timer);
    soft_timer_start(proc_timer);
    /*say hi */
    xlog_tag_message(TAG, "Initialize successfully\n");
}
